カスタムリソースを使用して CloudFormation スタックの削除時に S3 バケットと一緒にオブジェクトを削除する方法
はじめに
CloudFormation スタックを削除する際にカスタムリソースを使用して S3 バケットとオブジェクトを同時に削除する機会がありましたので、その方法について記載します。
前提として、CloudFormation で S3 バケットを作成します。
今回は以下のテンプレートで、バージョニングを有効化&任意のバケット名の S3 バケットを作成しました。
--- AWSTemplateFormatVersion: '2010-09-09' Resources: myBucketResource: Type: AWS::S3::Bucket Properties: BucketName: s3-bucket-cleaning-on-delete VersioningConfiguration: Status: Enabled
スタックの作成が完了すると、以下の通り S3 バケットが作成されます。
Lambda
次に Lambda 関数を作成します。
Lambda コンソールで「関数の作成」をクリックし、「一から作成」をして任意の関数名を入力します。
ランタイムは「Python3.7」を選択してその他はデフォルトのまま「関数の作成」をクリックします。
関数の作成が完了したら、参考 URL に記載のコードを一部修正してデプロイを行います。
#!/usr/bin/env python # -*- coding: utf-8 -*- import json import boto3 import requests # ベンダーバージョンのリクエストを削除 def lambda_handler(event, context): try: bucket = event['ResourceProperties']['BucketName'] if event['RequestType'] == 'Delete': s3 = boto3.resource('s3') bucket = s3.Bucket(bucket) for obj in bucket.objects.filter(): s3.Object(bucket.name, obj.key).delete() bucket.object_versions.delete() # コード追加 sendResponseCfn(event, context, "SUCCESS") except Exception as e: print(e) sendResponseCfn(event, context, "FAILED") def sendResponseCfn(event, context, responseStatus): response_body = {'Status': responseStatus, 'Reason': 'Log stream name: ' + context.log_stream_name, 'PhysicalResourceId': context.log_stream_name, 'StackId': event['StackId'], 'RequestId': event['RequestId'], 'LogicalResourceId': event['LogicalResourceId'], 'Data': json.loads("{}")} requests.put(event['ResponseURL'], data=json.dumps(response_body))
デプロイ後、設定タブから一般設定を選択して編集をクリックします。
タイムアウトを 10分 など長めの時間に変更したら「IAM コンソールでサービスロールを表示します」をクリックします。
IAM コンソールに移動したら「アクセス許可を追加」をクリックして「ポリシーをアタッチ」を選択します。 そして今回は AmazonS3FullAccess ポリシーを付与します。※ 必要に応じた権限の設定を行ってください。
CloudFormation
次に参考 URL をもとに CloudFormation テンプレートにカスタムリソースを追加してスタックを更新します。
ServiceToken では作成した Lambda の ARN を指定し、BucketName は S3 バケットの論理 ID を指定します。
--- AWSTemplateFormatVersion: '2010-09-09' Resources: myBucketResource: Type: AWS::S3::Bucket Properties: BucketName: s3-bucket-cleaning-on-delete VersioningConfiguration: Status: Enabled # カスタムリソースを追加 LambdaUsedToCleanUp: Type: Custom::cleanupbucket Properties: ServiceToken: arn:aws:lambda:us-west-2:XXXXXXXXXXXX:function:LambdaEmptyS3Objects BucketName: !Ref myBucketResource
テスト
カスタムリソースがうまく稼働するかどうかテストを行います。
作成した S3 バケットにオブジェクトを配置しました。
同オブジェクト名の Zip ファイルをアップロードしたので以下のようにバージョン管理されています。
上記で作成したスタックを削除すると、S3 バケットと一緒にバケット内のオブジェクトも削除されました。
おわりに
カスタムリソースでの対応方法は参考 URL に記載の内容とあらかた同じなのですが、ランタイムや IAM ロールの設定などで詰まるところがあったため、記事に残しました。この記事がどなたかのお役に立てれば幸いです。